package com.internetCafes.spms.web.certificate.controller;

import cn.hutool.core.util.ObjectUtil;
import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.module.excel.ExcelUtils;
import com.internetCafes.spms.common.module.excel.po.CertificateTransactionExcel;
import com.internetCafes.spms.common.module.excel.po.CertificateTransactionExcelPro;
import com.internetCafes.spms.common.utils.DateUtils;
import com.internetCafes.spms.common.utils.ExcelImportUtil;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.common.utils.entity.RR;
import com.internetCafes.spms.core.annotation.SysLog;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.core.model.pageModel.DataGrid;
import com.internetCafes.spms.core.utils.IdWorker;
import com.internetCafes.spms.core.utils.Query;
import com.internetCafes.spms.core.utils.R;
import com.internetCafes.spms.web.certificate.bizservice.CertTransactionBizService;
import com.internetCafes.spms.web.certificate.common.cont.CertConst;
import com.internetCafes.spms.web.certificate.common.cont.CertTransactionConst;
import com.internetCafes.spms.web.certificate.model.certificate.req.CertTransactionInfoReq;
import com.internetCafes.spms.web.certificate.model.dto.transaction.TransactionReturnDTO;
import com.internetCafes.spms.web.certificate.model.vo.project.CertificateTransactionOutProjectsVO;
import com.internetCafes.spms.web.certificate.model.vo.transaction.TransactionOutListVO;
import com.internetCafes.spms.web.certificate.entity.CertiTransactionInfo;
import com.internetCafes.spms.web.certificate.entity.CertificateInfo;
import com.internetCafes.spms.web.certificate.entity.EmployeeInfo;
import com.internetCafes.spms.web.certificate.service.CertiTransactionInfoService;
import com.internetCafes.spms.web.certificate.service.CertificateInfoService;
import com.internetCafes.spms.web.certificate.service.EmployeeInfoService;
import com.internetCafes.spms.web.certificate.vo.CertiTransactionInfoVo;
import com.internetCafes.spms.web.certificate.vo.CertificateInfoVo;
import com.internetCafes.spms.web.certificate.vo.CollectInfo;
import com.internetCafes.spms.web.customer.service.user.IEntUserInfoService;
import com.internetCafes.spms.web.project.service.IProjectConfigService;
import com.internetCafes.spms.web.sys.model.ResourceInfo;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.ResourceInfoService;
import com.internetCafes.spms.web.tenant.model.TenantDeptInfo;
import com.internetCafes.spms.web.tenant.service.TenantDeptInfoService;
import com.sms.common.util.hutool.core.bean.BeanUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecgframework.poi.excel.entity.ImportSheetParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 证书借还历史
 *
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2019-10-31 18:10:59
 */
@Api(tags = {">>>证书流转"})
@RestController
@RequestMapping("/certificate/certiTransactionInfo")
public class CertiTransactionInfoController {

    @Value("${system.upload.others}")
    private String othersPath;

    @Autowired
    private CertiTransactionInfoService certiTransactionInfoService;

    @Autowired
    private CertificateInfoService certificateInfoService;

    @Autowired
    private EmployeeInfoService employeeInfoService;

    @Autowired
    private TenantDeptInfoService tenantDeptInfoService;

    @Autowired
    private ResourceInfoService resourceInfoService;

    @Autowired
    private IProjectConfigService projectConfigService;

    @Autowired
    private IEntUserInfoService userInfoService;

    @Autowired
    private CertTransactionBizService transactionBizService;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @ApiOperation(value = "证书借出获取项目列表")
    @GetMapping("/transactionOut/projects")
    @RequiresPermissions("certificate:certificateInfo:update")
    public RR<List<CertificateTransactionOutProjectsVO>> transactionOutProjects() {
        List<CertificateTransactionOutProjectsVO> result = projectConfigService.transactionOutProjects();
        return new RR<>().successData(result);
    }

    /**
     * 证书还回修改接口
     */
    @ApiOperation(value = "证书还回修改")
    @PostMapping("/transaction/return/update")
    public RR<Void> transactionReturnUpdate(@RequestBody TransactionReturnDTO dto) {
        certiTransactionInfoService.transactionReturnUpdate(dto);
        return RR.success("修改成功");
    }

    /**
     * 获取证书借出项目列表
     */
    @ApiOperation(value = "获取证书借出项目列表")
    @GetMapping("/transaction/out/projects/{certificateId}")
    @ApiParam(required = true, name = "certificateId", value = "证书专业id")
    public RR<List<TransactionOutListVO>> transactionOutProjects(@PathVariable("certificateId") Long certificateId) {
        List<TransactionOutListVO> results = certiTransactionInfoService.transactionOutProjects(certificateId);
        return new RR<>().successData(results);
    }

    /**
     * 证书还回接口
     */
    @ApiOperation(value = "证书还回")
    @PostMapping("/transaction/return")
    public RR<Void> transactionReturn(@RequestBody TransactionReturnDTO dto) {
        CertiTransactionInfo transactionOutInfo = certiTransactionInfoService.findById(dto.getId());
        if (transactionOutInfo == null) {
            throw new RRException("记录不存在");
        }
        if (transactionOutInfo.getStatusTag().equals(CommonConstants.CertiTransactionStatusTags.COMPLETE.getTag())) {
            throw new RRException("借出已还回");
        }
        CertificateInfo certificateInfo = certificateInfoService.findById(transactionOutInfo.getCertificateId());

        CertTransactionInfoReq transactionInfoReq = new CertTransactionInfoReq();
        transactionInfoReq.setReturnFromId(dto.getId());
        transactionInfoReq.setRemark(dto.getRemark());
        transactionInfoReq.setCertInfoPo(certificateInfo);
        transactionBizService.borrowOutReturn(transactionInfoReq);
        return RR.success("还回成功");
    }

    /**
     * 证书借出信息修改
     */
    @SysLog("证书借出信息修改")
    @PostMapping("/transaction/out/update")
    @RequiresPermissions("certificate:certiTransactionInfo:update")
    public R transactionOutUpdate(@RequestBody CertiTransactionInfoVo certiTransactionInfo) {
        return certiTransactionInfoService.certificateBorrowOutUpdate(certiTransactionInfo);
    }

    /**
     * 证书借出接口
     */
    @SysLog("证书借出")
    @PostMapping("/transaction/out")
    @RequiresPermissions("certificate:certiTransactionInfo:save")
    public R transactionOut(@RequestBody CertiTransactionInfoVo certiTransactionInfo) {

        CertificateInfo certificateInfo = certificateInfoService.findById(certiTransactionInfo.getCertificateId());
        if (ObjectUtil.isNull(certificateInfo)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }
        if (certificateInfo.getDisable()) {
            throw new RRException(RRExceptionCodeEnum.CERT_CERTIFICATE_OVERDUE);
        }
        CertTransactionInfoReq certTransactionInfoReq = cn.hutool.core.bean.BeanUtil.toBean(certiTransactionInfo, CertTransactionInfoReq.class);
        certTransactionInfoReq.setCertInfoPo(certificateInfo);
        transactionBizService.borrowOut(certTransactionInfoReq);
        Map<String, Object> params = new HashMap<>();
        params.put("certificateId", certiTransactionInfo.getCertificateId());
        List<CertiTransactionInfo> certiTransactionInfos = certiTransactionInfoService.query(params);
        certiTransactionInfoService.saveResource(certiTransactionInfo);
        return R.ok().put("c", certificateInfo).put("ctList", certiTransactionInfos);
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("certificate:certiTransactionInfo:list")
    public R list(@RequestParam Map<String, Object> params, HttpServletRequest request) {
        //查询列表数据
        Query query = new Query(params);

        String tenantId = request.getParameter("tenantId");
        String certificateId = request.getParameter("certificateId");
        String type = request.getParameter("type");
        String certificateType = request.getParameter("certificateType");
        String keepDeptId = request.getParameter("keepDeptId");
        String keepUserId = request.getParameter("keepUserId");
        String name = request.getParameter("name");
        String pIdType = request.getParameter("idType");
        String idType = request.getParameter("idType");
        String idCard = request.getParameter("idCard");
        String certificateNo = params.get("certificateNo") == null ? "" : params.get("certificateNo").toString();
        /*String certificateNo = request.getParameter("certificateNo");*/
        String mobile = request.getParameter("mobile");
        String profession = request.getParameter("profession");
        String academic = request.getParameter("academic");
        String releaseTime = request.getParameter("releaseTime");
        String validityEndTime = request.getParameter("validityEndTime");
        String validityType = request.getParameter("validityType");
        String months = request.getParameter("months");
        String days = request.getParameter("days");
        String orderBy = request.getParameter("orderBy");
        String inOrder = request.getParameter("inOrder");
        String status = request.getParameter("status");
        String toUserMobile = request.getParameter("toUserMobile");
        String transactionTime = request.getParameter("transactionTime");
        String transactionEndTime = request.getParameter("transactionEndTime");
        params = new HashMap<>();
        if (StringUtils.isNotBlank(certificateType)) {
            params.put("certificateType", Integer.parseInt(certificateType));
        }

        if (StringUtils.isNotBlank(pIdType)) {
            params.put("pIdType", pIdType);
        }

        if (StringUtils.isNotBlank(keepDeptId)) {
            params.put("keepDeptId", Long.parseLong(keepDeptId));
        }

        if (StringUtils.isNotBlank(keepUserId)) {
            params.put("keepUserId", Long.parseLong(keepUserId));
        }

        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }

        if (StringUtils.isNotBlank(idType)) {
            params.put("idType", idType);
        }

        if (StringUtils.isNotBlank(idCard)) {
            params.put("idCard", idCard);
        }

        if (StringUtils.isNotBlank(certificateNo)) {
            params.put("certificateNo", certificateNo);
        }

        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }

        if (StringUtils.isNotBlank(profession)) {
            params.put("profession", profession);
        }

        if (StringUtils.isNotBlank(academic)) {
            params.put("academic", academic);
        }

        if (StringUtils.isNotBlank(releaseTime)) {
            params.put("releaseTime", DateUtils.strToDate(releaseTime));
        }

        if (StringUtils.isNotBlank(validityEndTime)) {
            params.put("validityEndTime", DateUtils.strToDate(validityEndTime));
        }

        if (StringUtils.isNotBlank(toUserMobile)) {
            params.put("toUserMobile", Long.parseLong(toUserMobile));
        }

        if (StringUtils.isNotBlank(type)) {
            params.put("type", type);
        }

        if (StringUtils.isNotBlank(orderBy)) {
            if ("type".equals(orderBy)) {
                orderBy = "t.type";
            }
            params.put("orderBy", com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(orderBy));
        }

        if (StringUtils.isNotBlank(inOrder)) {
            params.put("inOrder", inOrder);
        }

        if (StringUtils.isNotBlank(validityType)) {
            switch (validityType) {
                case "0":
                    if (StringUtils.isNotBlank(months)) {
                        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    }
                    if (StringUtils.isNotBlank(days)) {
                        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(Integer.parseInt(days)));
                    }
                    break;
                case "-1":
                    params.put("ivalidity", "");
                    break;
                case "2":
                    if (StringUtils.isNotBlank(months)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    }
                    if (StringUtils.isNotBlank(days)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(Integer.parseInt(days)));
                    }
                    break;
            }
        }

        if (StringUtils.isNotBlank(tenantId)) {
            params.put("tenantId", tenantId);
        } else {
            UserInfo userInfo = ShiroUtils.getUserEntity();
            if (com.sms.common.util.hutool.core.util.ObjectUtil.isNotNull(userInfo.getTenantId()) && !userInfo.getTenantId().equals(0)) {
                params.put("tenantId", userInfo.getTenantId());
            }
        }

        if (StringUtils.isNotBlank(certificateId)) {
            params.put("certificateId", Long.parseLong(certificateId));
        }

        if (StringUtils.isNotBlank(transactionTime)) {
            params.put("transactionTime", transactionTime);
        }

        if (StringUtils.isNotBlank(transactionEndTime)) {
            params.put("transactionEndTime", transactionEndTime);
        }

        if (StringUtils.isNotBlank(status)) {
            if ("crash".equals(status)) {
                params.put("status", CommonConstants.CertificateStatus.DELETE);
            } else {
                params.put("status", Integer.parseInt(status));
            }
        } else {
            params.put("statuses", CommonConstants.CertificateStatus.EXCEPT_DELETE);
        }

        DataGrid dataGrid = certiTransactionInfoService.dataGrid(params, query.getPage(), query.getLimit());

        return R.ok().put("page", dataGrid);
    }


    /**
     * 列表
     */
    @RequestMapping("/getTransactions")
    @RequiresPermissions("certificate:certiTransactionInfo:list")
    public R getTransactions(Long id) {
        CertiTransactionInfo ct = certiTransactionInfoService.findById(id);
        Map<String, Object> params = new HashMap<>();
        params.put("id", ct.getCertificateId());
        List<CertificateInfoVo> certificateInfoVoList = certificateInfoService.selectByJobParams(params);
        CertificateInfoVo c = null;
        if (CollectionUtils.isNotEmpty(certificateInfoVoList)) {
            c = certificateInfoVoList.get(0);
            params = new HashMap<>();
            params.put("moduleId", c.getId());
            params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Certi);
            List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
            if (CollectionUtils.isNotEmpty(resourceInfoList)) {
                c.setCertifInfoList(resourceInfoList);
            }

            params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Constrat);
            resourceInfoList = resourceInfoService.query(params);
            if (CollectionUtils.isNotEmpty(resourceInfoList)) {
                c.setContractInfoList(resourceInfoList);
            }
        }
        params = new HashMap<>();
        params.put("certificateId", ct.getCertificateId());
        List<CertiTransactionInfo> certiTransactionInfoList = certiTransactionInfoService.query(params);
        return R.ok().put("c", c).put("ct", ct).put("ctList", certiTransactionInfoList);
    }

    /**
     * 列表
     */
    @RequestMapping("/getAllList")
    @RequiresPermissions("certificate:certiTransactionInfo:list")
    public R getAllList(@RequestParam Map<String, Object> params, HttpServletRequest request) {
        Query query = new Query(params);
        String certificateId = request.getParameter("certificateId");
        params = new HashMap<>();
        if (StringUtils.isNotBlank(certificateId)) {
            params.put("certificateId", certificateId);
        }
        int pageNo = query.getPage();
        Integer pageSize = query.getLimit();
        params.put("page", (pageNo - 1 < 0 ? -1 : pageNo - 1) * pageSize);
        params.put("rows", pageSize);
        List<CertiTransactionInfo> resultList = certiTransactionInfoService.query(params);
        for (CertiTransactionInfo certiTransactionInfo : resultList) {
            if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction) {
                CertificateInfo certificateInfo = certificateInfoService.findById(certiTransactionInfo.getCertificateId());
                certiTransactionInfo.setUsage(certificateInfo.getStatus());
            }
            if (certiTransactionInfo.getToUserName() == null) {
                EmployeeInfo e = employeeInfoService.findById(certiTransactionInfo.getToUserId());
                if (e != null) {
                    certiTransactionInfo.setToUserName(e.getName());
                }
            }
            if (certiTransactionInfo.getToDeptName() == null) {
                TenantDeptInfo d = tenantDeptInfoService.findById(certiTransactionInfo.getToDeptId());
                if (d != null) {
                    certiTransactionInfo.setToDeptName(d.getDeptName());
                }
            }
        }
        // 对证书旧数据进行判断**/
        params = new HashMap<>();
        params.put("certificateId", certificateId);
        params.put("types", new Integer[]{
                CommonConstants.CertiTransactionInfoType.Transaction,
                CommonConstants.CertiTransactionInfoType.Transaction_Return});
        List<CertiTransactionInfo> certificateTransactions = certiTransactionInfoService.query(params);
        long oldDataAmount = certificateTransactions.stream()
                .filter(transaction -> transaction.getStatusTag() == null)
                .count();
        if ((oldDataAmount % 2L) == 0L) {
            resultList.forEach(result -> {
                if (result.getStatusTag() == null
                        && result.getType().equals(CommonConstants.CertiTransactionInfoType.Transaction)) {
                    result.setStatusTag(1);
                }
            });
        } else {
            // 找到最后一个id
            CertiTransactionInfo finalTransaction = certificateTransactions.stream()
                    .filter(transaction -> transaction.getStatusTag() == null
                            && transaction.getType().equals(CommonConstants.CertiTransactionInfoType.Transaction))
                    .max(Comparator.comparingLong(CertiTransactionInfo::getId)).get();
            resultList.forEach(result -> {
                if (result.getStatusTag() == null
                        && result.getType().equals(CommonConstants.CertiTransactionInfoType.Transaction)) {
                    if (result.getId().equals(finalTransaction.getId())) {
                        result.setStatusTag(0);
                    } else {
                        result.setStatusTag(1);
                    }
                }
            });
        }
        long count = certiTransactionInfoService.count(params);
        return R.ok().put("data", resultList)
                .put("count", count)
                .put("pageSize", pageSize)
                .put("pageNo", pageNo);
    }


    /**
     * 根据ID获取数据
     */
    @RequestMapping("/info/{id}")
    @RequiresPermissions("certificate:certiTransactionInfo:info")
    public R info(@PathVariable("id") Long id) {
        CertiTransactionInfo certiTransactionInfo = certiTransactionInfoService.findById(id);
        if (certiTransactionInfo.getAffiliationEmployee() != null) {
            EmployeeInfo employeeInfo = employeeInfoService.findById(certiTransactionInfo.getAffiliationEmployee());
            certiTransactionInfo.setAffiliationEmployeeName(employeeInfo.getName());
        }
        Map<String, Object> params = new HashMap<>();
        params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Pay);
        params.put("moduleId", id);
        List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
        return R.ok().put("certiTransactionInfo", certiTransactionInfo).put("payPicList", resourceInfoList);
    }


    /**
     * 保存
     */
    @SysLog("批量保存人员证书流转记录")
    @RequestMapping("/batchSave")
    @RequiresPermissions("certificate:certiTransactionInfo:save")
    public R batchSave(MultipartFile file) {
        List<R> resultList = new ArrayList<>();
        int countFail = 0;
        if (file.isEmpty()) {
            throw new RRException("上传文件不能为空");
        }

        IdWorker id = new IdWorker(2);
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File videoFilePath = new File(othersPath);
        if (!videoFilePath.exists()) {
            videoFilePath.mkdirs();
        }
        List<CertificateTransactionExcel> dealInfoExcelList = null;
        if (fileType.toUpperCase().endsWith("XLS") || fileType.toUpperCase().endsWith("XLSX")) {
            String filePath = othersPath + File.separator + id.nextId() + fileType;

            try {
                file.transferTo(new File(filePath));
            } catch (IOException e) {
                e.printStackTrace();
            }

            Map<String, ImportSheetParams> sheetClassParamsMap = new HashMap<>();
            Map<String, Object> excel2Map;
            sheetClassParamsMap.put("Sheet1", new ImportSheetParams("certificateTransactionExcel", 1, 1, new String[]{"操作类型", "证书编号", "接收单位", "接收人联系方式", "接收人姓名", "挂出/借出时间", "返还时间", "挂出人", "挂出收入", "猎头支出", "其他支出", "是否打款", "打款时间", "是否税后", "费用说明", "备注"}, CertificateTransactionExcel.class));
            try {
                excel2Map = ExcelImportUtil.importExcel2Map(new File(filePath), sheetClassParamsMap, null);
            } catch (Exception e) {
                return R.error(e.getMessage());
            }
            dealInfoExcelList = (List<CertificateTransactionExcel>) excel2Map.get("Sheet1");
            for (CertificateTransactionExcel certificateTransactionExecl : dealInfoExcelList) {
                CertiTransactionInfoVo certiTransactionInfo = new CertiTransactionInfoVo();
                BeanUtil.copyProperties(certificateTransactionExecl, certiTransactionInfo);
                String certificateNo = certificateTransactionExecl.getCertificateNo();
                Map<String, Object> params = new HashMap<>();
                params.put("certificateNo", certificateNo);
                List<CertificateInfo> certificateInfoList = certificateInfoService.query(params);
                if (certificateInfoList.size() == 0) {
                    R error = R.error("未找到对应证书");
                    error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                    error.put("type", certificateTransactionExecl.getType());
                    resultList.add(error);
                    countFail++;
                    continue;
                }
                if (certificateInfoList.get(0).getStatus() != CommonConstants.CertificateStatus.NO_USE &&
                        certificateInfoList.get(0).getStatus() != CommonConstants.CertificateStatus.BORROW_IN) {
                    R error = R.error("证书为非空闲状态");
                    error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                    error.put("type", certificateTransactionExecl.getType());
                    resultList.add(error);
                    countFail++;
                    continue;
                }
                certiTransactionInfo.setCreateBy(ShiroUtils.getUserId());
                certiTransactionInfo.setCreateTime(new Date());
                certiTransactionInfo.setCertificateId(certificateInfoList.get(0).getId());
                if (certificateTransactionExecl.getType() == CommonConstants.CertiTransactionInfoType.BorrowOut) {
                    if (certiTransactionInfo.getAffiliationEmployeeName() != null) {
                        params = new HashMap<>();
                        params.put("name", certiTransactionInfo.getAffiliationEmployeeName());
                        List<EmployeeInfo> employeeInfos = employeeInfoService.query(params);
                        if (CollectionUtils.isEmpty(employeeInfos)) {
                            R error = R.error("该挂出人人在当前系统中不存在");
                            error.put("name", certiTransactionInfo.getAffiliationEmployeeName());
                            resultList.add(error);
                            countFail++;
                            continue;
                        } else {
                            certiTransactionInfo.setAffiliationEmployee(employeeInfos.get(0).getId());
                        }
                    }
                    certiTransactionInfo.setToDeptName(certificateTransactionExecl.getToDeptName());
                    certiTransactionInfo.setToUserName(certificateTransactionExecl.getToUserName());
                    R save = save(certiTransactionInfo);
                    if (Integer.parseInt(save.get("code").toString()) != 0) {
                        R error = R.error((String) save.get("msg"));
                        error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                        error.put("type", certificateTransactionExecl.getType());
                        resultList.add(error);
                        countFail++;
                    }
                    continue;
                }
                if (certificateTransactionExecl.getType() == CommonConstants.CertiTransactionInfoType.Transaction) {
                    params = new HashMap<>();
                    params.put("deptName", certificateTransactionExecl.getToDeptName());
                    TenantDeptInfo tenantDeptInfo = tenantDeptInfoService.findFirst(params);
                    if (tenantDeptInfo == null) {
                        R error = R.error("未找到对应部门");
                        error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                        error.put("type", CommonConstants.CertiTransactionInfoType.Transaction);
                        resultList.add(error);
                        countFail++;
                        continue;
                    }
                    certiTransactionInfo.setToDeptId(tenantDeptInfo.getId());
                    certiTransactionInfo.setTenantId(tenantDeptInfo.getTenantId());
                    params = new HashMap<>();
                    params.put("name", certificateTransactionExecl.getToUserName());
                    params.put("deptId", tenantDeptInfo.getId());
                    EmployeeInfo employeeInfo = employeeInfoService.findFirst(params);
                    if (employeeInfo == null) {
                        R error = R.error("未找到接收人");
                        error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                        error.put("type", certificateTransactionExecl.getType());
                        resultList.add(error);
                        countFail++;
                        continue;
                    }
                    certiTransactionInfo.setToUserId(employeeInfo.getId());
                    // 添加完成标签
                    R save = save(certiTransactionInfo);
                    if (Integer.parseInt(save.get("code").toString()) != 0) {
                        R error = R.error((String) save.get("msg"));
                        error.put("certificateNo", certificateTransactionExecl.getCertificateNo());
                        error.put("type", certificateTransactionExecl.getType());
                        resultList.add(error);
                        countFail++;
                    }
                }
            }
        }
        R ok = R.ok();
        ok.put("success", dealInfoExcelList.size() - countFail)
                .put("fail", countFail)
                .put("data", resultList);
        return ok;

    }

    /**
     * 保存
     */
    @SysLog("保存人员证书流转记录")
    @RequestMapping("/save")
    @RequiresPermissions(value = {"certificate:certiTransactionInfo:save", "certificate:certificateInfo:update"}, logical = Logical.OR)
    public R save(@RequestBody CertiTransactionInfoVo certiTransactionInfo) {
        List<CertiTransactionInfo> certiTransactionInfoList;
        CertificateInfo c = certificateInfoService.findById(certiTransactionInfo.getCertificateId());
        EmployeeInfo u = employeeInfoService.findById(c.getEmployeeId());
        // CertTransactionInfoReq certTransactionInfoReq = cn.hutool.core.bean.BeanUtil.toBean(certiTransactionInfo, CertTransactionInfoReq.class);
        // certTransactionBizService.save(certTransactionInfoReq);
        certiTransactionInfo.setTenantId(u.getTenantId());
        certiTransactionInfo.setCertificateId(c.getId());
        certiTransactionInfo.setCreateTime(new Date());
        certiTransactionInfo.setCreateBy(ShiroUtils.getUserId());
        CertTransactionInfoReq transactionInfoReq = cn.hutool.core.bean.BeanUtil.toBean(certiTransactionInfo, CertTransactionInfoReq.class);
        transactionInfoReq.setCertInfoPo(c);
        if (CertTransactionConst.Type.AFFILIATION_OUT.getId().equals(certiTransactionInfo.getType())) {
            if (c.getDisable()) {
                throw new RRException(RRExceptionCodeEnum.CERT_CERTIFICATE_OVERDUE);
            }
            transactionBizService.affiliationOut(transactionInfoReq);
        } else if (CertTransactionConst.Type.BORROW_OUT.getId().equals(certiTransactionInfo.getType())) {
            // 借出
            if (c.getDisable()) {
                throw new RRException(RRExceptionCodeEnum.CERT_CERTIFICATE_OVERDUE);
            }
            transactionBizService.borrowOut(transactionInfoReq);
        } else if (CertTransactionConst.Type.AFFILIATION_OUT_RETURN.getId().equals(certiTransactionInfo.getType())) {
            // 收回
            transactionBizService.affiliationOutReturn(transactionInfoReq);
        } else if (CertTransactionConst.Type.BORROW_OUT_RETURN.getId().equals(certiTransactionInfo.getType())) {
            //还回
            throw new RRException(RRExceptionCodeEnum.NO_AUTHORITY);
        } else if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowIn_Return) {
            c.setStatus(CommonConstants.CertificateStatus.BORROW_IN_RETURN);
            certificateInfoService.update(c);
            certiTransactionInfo.setFromDeptId(c.getKeepDeptId());
            certiTransactionInfo.setFromDeptName(c.getKeepDeptName());
            certiTransactionInfo.setFromUserId(c.getKeepUserId());
            certiTransactionInfo.setFromUserName(c.getKeepUserName());
            certiTransactionInfo.setFromUserMobile(c.getKeepContactMobile());
            certiTransactionInfoService.save(certiTransactionInfo);
        } else {
            EmployeeInfo e = employeeInfoService.findById(certiTransactionInfo.getToUserId());
            TenantDeptInfo d = tenantDeptInfoService.findById(certiTransactionInfo.getToDeptId());
            certiTransactionInfo.setToUserName(e.getName());
            certiTransactionInfo.setToDeptName(d.getDeptName());
            certiTransactionInfoService.save(certiTransactionInfo);
        }
        Map<String, Object> params = new HashMap<>();
        params.put("certificateId", certiTransactionInfo.getCertificateId());
        certiTransactionInfoList = certiTransactionInfoService.query(params);
        certiTransactionInfoService.saveResource(certiTransactionInfo);
        return R.ok().put("c", c).put("ctList", certiTransactionInfoList);
    }

    /**
     * 批量挂还
     */
    @SysLog("人员证书批量挂还")
    @PostMapping("/batchReturnSave")
    @RequiresPermissions(value = {"certificate:certiTransactionInfo:save", "certificate:certificateInfo:update"}, logical = Logical.OR)
    public R saveBatchReturn(@RequestBody List<CertiTransactionInfoVo> certiTransactionInfo) {
        // 获取证书列表
        List<Long> certificateIdList
                = certiTransactionInfo
                .stream()
                .map(CertiTransactionInfoVo::getCertificateId)
                .collect(Collectors.toList());
        Map<String, Object> params = new HashMap<>();
        params.put("ids", certificateIdList);
        Map<Long, CertificateInfo> certMapById = certificateInfoService.query(params).stream()
                .collect(Collectors.toMap(CertificateInfo::getId, Function.identity()));
        List<CertTransactionInfoReq> transactionInfoReqList = new ArrayList<>();
        CertTransactionInfoReq transactionInfoReq;
        for (CertiTransactionInfoVo certiTransactionInfoVo : certiTransactionInfo) {
            if (!certMapById.containsKey(certiTransactionInfoVo.getCertificateId())) {
                throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
            }
            transactionInfoReq
                    = cn.hutool.core.bean.BeanUtil.toBean(certiTransactionInfoVo, CertTransactionInfoReq.class);
            CertificateInfo certificateInfoPo = certMapById.get(certiTransactionInfoVo.getCertificateId());
            // 未挂出的证书不支持收回
            if (!CertConst.Status.BORROW_OUT.getId().equals(certificateInfoPo.getStatus())) {
                throw new RRException(RRExceptionCodeEnum.CERT_CERTIFICATE_NOT_AFFILIATION_OUT);
            }
            transactionInfoReq.setCertInfoPo(certMapById.get(certiTransactionInfoVo.getCertificateId()));
            transactionInfoReqList.add(transactionInfoReq);
        }
        transactionBizService.affiliationOutReturnBatchByCertIdList(transactionInfoReqList);

        return R.ok().put("c", certiTransactionInfo).put("ctList", transactionInfoReqList);
    }


    /**
     * 修改
     */
    @SysLog("修改人员证书流转记录")
    @RequestMapping("/update")
    @RequiresPermissions(value = {"certificate:certiTransactionInfo:update", "certificate:certificateInfo:update"}, logical = Logical.OR)
    public R update(@RequestBody CertiTransactionInfoVo certiTransactionInfo) {
        // 获取该证书的修改历史对象
        CertiTransactionInfo t = certiTransactionInfoService.findById(certiTransactionInfo.getId());
        // 获取该证书对象
        CertificateInfo c = certificateInfoService.findById(t.getCertificateId());

        /*
        设置 证书修改历史对象
        判断证书状态类型是否相同  例：11挂入,12归还,21挂出,22收回,31借出,32还回
         */
        if (certiTransactionInfo.getType().equals(t.getType())) {
            CertiTransactionInfo transactionInfo = new CertiTransactionInfo();
            BeanUtil.copyProperties(certiTransactionInfo, transactionInfo);
            if (transactionInfo.getUsage() != null && (transactionInfo.getUsage() == CommonConstants.CertificateStatus.BID_USED ||
                    transactionInfo.getUsage() == CommonConstants.CertificateStatus.PROJECT_USED ||
                    transactionInfo.getUsage() == CommonConstants.CertificateStatus.BID_SUCCESS ||
                    transactionInfo.getUsage() == CommonConstants.CertificateStatus.OTHER_STATUS)) {
                c.setStatus(certiTransactionInfo.getUsage());
                String remark = transactionInfo.getRemark();
                int start = remark.indexOf("[");
                int end = remark.indexOf("] ");
                if (start > end) {
                    String substring = remark.substring(start + 1, end);
                    String usage = "项目";
                    if (certiTransactionInfo.getUsage() > 0) {
                        usage = CommonConstants.CertificateStatus.getDescr(certiTransactionInfo.getUsage());
                    }
                    remark = remark.replace(substring, usage);
                    transactionInfo.setRemark(remark);
                }
            }
            if (certiTransactionInfo.getToUserId() != null) {
                EmployeeInfo e = employeeInfoService.findById(certiTransactionInfo.getToUserId());
                transactionInfo.setToUserName(e.getName());
            }
            if (certiTransactionInfo.getToDeptId() != null) {
                TenantDeptInfo d = tenantDeptInfoService.findById(certiTransactionInfo.getToDeptId());
                transactionInfo.setToDeptName(d.getDeptName());
            }
            if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowIn) {
                EmployeeInfo e = employeeInfoService.findById(certiTransactionInfo.getToUserId());
                TenantDeptInfo d = tenantDeptInfoService.findById(certiTransactionInfo.getToDeptId());
                certiTransactionInfo.setToUserName(e.getName());
                certiTransactionInfo.setToDeptName(d.getDeptName());
            }
            certiTransactionInfo.setUpdateTime(new Date());
            certiTransactionInfo.setUpdateBy(ShiroUtils.getUserId());


            // 持久化修改信息对象
            certiTransactionInfoService.update(transactionInfo);
            // 持久化证书信息对象
            int update = certificateInfoService.update(c);
            logger.info("修改" + update + "条流转记录");
            return R.ok().put("c", c).put("ct", t);
        }

        if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowIn_Return ||
                certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowOut_Return ||
                certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction ||
                certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction_Return) {

            certiTransactionInfo.setTenantId(t.getTenantId());
            certiTransactionInfo.setCertificateId(c.getId());
            int type = -99;
            // 借出

            if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction) {
                certiTransactionInfo.setFromDeptName(t.getToDeptName());
                certiTransactionInfo.setFromDeptId(t.getToDeptId());
                certiTransactionInfo.setFromUserName(t.getToUserName());
                certiTransactionInfo.setFromUserId(t.getToUserId());
                EmployeeInfo e = employeeInfoService.findById(certiTransactionInfo.getToUserId());
                TenantDeptInfo d = tenantDeptInfoService.findById(certiTransactionInfo.getToDeptId());
                certiTransactionInfo.setToUserName(e.getName());
                certiTransactionInfo.setToDeptName(d.getDeptName());
                String usage = "项目";
                type = CommonConstants.CertificateStatus.PROJECT_USED;
                if (certiTransactionInfo.getUsage() > 0) {
                    type = certiTransactionInfo.getUsage();
                    usage = CommonConstants.CertificateStatus.getDescr(certiTransactionInfo.getUsage());
                }
                certiTransactionInfo.setRemark("[" + usage + "] " + certiTransactionInfo.getRemark());
            }

            // 归还
            else if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowIn_Return) {
                certiTransactionInfo.setFromDeptName(c.getKeepDeptName());
                certiTransactionInfo.setFromDeptId(c.getKeepDeptId());
                certiTransactionInfo.setFromUserName(c.getKeepUserName());
                certiTransactionInfo.setFromUserId(c.getKeepUserId());
                certiTransactionInfo.setToDeptName(c.getBorrowOrgName());
                certiTransactionInfo.setToUserName(c.getKeepUserName());
                certiTransactionInfo.setToUserMobile(c.getBorrowContactMobile());
                type = CommonConstants.CertificateStatus.BORROW_IN_RETURN;
            }

            // 还回
            else if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction_Return) {
                certiTransactionInfo.setFromDeptName(t.getToDeptName());
                certiTransactionInfo.setFromDeptId(t.getToDeptId());
                certiTransactionInfo.setFromUserName(t.getToUserName());
                certiTransactionInfo.setFromUserId(t.getToUserId());
                certiTransactionInfo.setToUserMobile(t.getToUserMobile());

                if (c.getOriKeepUserId() == null || c.getOriKeepDeptId() == null) {
                    EmployeeInfo u = employeeInfoService.findById(ShiroUtils.getUserEntity().getUserId());
                    c.setOriKeepUserId(u.getId());
                    c.setOriKeepUserName(u.getName());
                    c.setOriKeepContactMobile(u.getMobile());
                    c.setOriKeepDeptId(u.getDeptId());
                    TenantDeptInfo d = tenantDeptInfoService.findById(u.getDeptId());
                    c.setOriKeepDeptName(d.getDeptName());

                    c.setKeepDeptId(c.getOriKeepDeptId());
                    c.setKeepDeptName(c.getOriKeepDeptName());
                    c.setKeepUserId(u.getId());
                    c.setKeepUserName(u.getName());
                    c.setKeepContactMobile(c.getOriKeepContactMobile());
                } else {
                    c.setKeepUserId(t.getFromUserId());
                    c.setKeepUserName(t.getFromUserName());
                    c.setKeepContactMobile(t.getFromUserMobile());
                    c.setKeepDeptId(t.getFromDeptId());
                    c.setKeepDeptName(t.getFromDeptName());
                }

                certiTransactionInfo.setToDeptId(c.getOriKeepDeptId());
                certiTransactionInfo.setToDeptName(c.getOriKeepDeptName());
                certiTransactionInfo.setToUserId(c.getOriKeepUserId());
                certiTransactionInfo.setToUserName(c.getOriKeepUserName());
                certiTransactionInfo.setToUserMobile(c.getOriKeepContactMobile());
                certiTransactionInfo.setTransactionTime(new Date());
                type = CommonConstants.CertificateStatus.NO_USE;
            }

            // 收回
            else if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.BorrowOut_Return) {
                certiTransactionInfo.setFromDeptName(t.getToDeptName());
                certiTransactionInfo.setFromUserName(t.getToUserName());
                certiTransactionInfo.setFromUserMobile(t.getToUserMobile());

                certiTransactionInfo.setToDeptName(t.getFromDeptName());
                certiTransactionInfo.setToUserName(t.getFromUserName());
                certiTransactionInfo.setToDeptId(t.getFromDeptId());
                certiTransactionInfo.setToUserId(t.getFromUserId());
                type = CommonConstants.CertificateStatus.NO_USE;
            }

            certiTransactionInfo.setCreateTime(new Date());
            certiTransactionInfo.setCreateBy(ShiroUtils.getUserId());
            certiTransactionInfoService.save(certiTransactionInfo);

            if (certiTransactionInfo.getType() == CommonConstants.CertiTransactionInfoType.Transaction) {
                if (c.getOriKeepDeptId() != null && c.getOriKeepUserId() != null && c.getOriKeepDeptId().longValue() == certiTransactionInfo.getToDeptId().longValue() && c.getOriKeepUserId().longValue() == certiTransactionInfo.getToUserId().longValue()) {
                    type = CommonConstants.CertificateStatus.NO_USE;
                    c.setKeepUserId(c.getOriKeepUserId());
                    c.setKeepUserName(c.getOriKeepUserName());
                    c.setKeepContactMobile(c.getOriKeepContactMobile());
                    c.setKeepDeptId(c.getOriKeepDeptId());
                    c.setKeepDeptName(c.getOriKeepDeptName());
                } else {
                    c.setKeepDeptId(certiTransactionInfo.getToDeptId());
                    c.setKeepDeptName(certiTransactionInfo.getToDeptName());
                    c.setKeepUserId(certiTransactionInfo.getToUserId());
                    c.setKeepUserName(certiTransactionInfo.getToUserName());
                    c.setKeepContactMobile(certiTransactionInfo.getToUserMobile());
                }
            }

            if (type != -99) {
                c.setStatus(type);
            }
            certificateInfoService.update(c);
        }
        certiTransactionInfoService.updateResource(certiTransactionInfo);
        return R.ok().put("c", c).put("ct", certiTransactionInfo);
    }


    /**
     * 删除
     */
    @SysLog("作废人员证书流转记录")
    @RequestMapping("/delete")
    @RequiresPermissions("certificate:certiTransactionInfo:delete")
    public R delete(@RequestBody Long[] ids) {
        certiTransactionInfoService.deleteBatch(ids);
        return R.ok();
    }

    /**
     * 获取近三个月内各类型借还记录数量
     */
    @GetMapping("/countThreeMonths")
    @RequiresPermissions("certificate:certiTransactionInfo:delete")
    public R countThreeMonths() {
        HashMap<String, Object> params = new HashMap<>();
        params.put("betweenDate", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(-3));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        Long borrowInThreeMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        Long borrowInReturnThreeMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        Long borrowOutThreeMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut_Return);
        Long borrowOutReturnThreeMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction);
        Long transactionThreeMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction_Return);
        Long transactionReturnThreeMonths = certiTransactionInfoService.count(params);
        params.put("betweenDate", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(-2));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        Long borrowInTwoMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        Long borrowInReturnTwoMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        Long borrowOutTwoMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut_Return);
        Long borrowOutReturnTwoMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction);
        Long transactionTwoMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction_Return);
        Long transactionReturnTwoMonths = certiTransactionInfoService.count(params);
        params.put("betweenDate", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(-1));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        Long borrowInOneMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        Long borrowInReturnOneMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        Long borrowOutOneMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut_Return);
        Long borrowOutReturnOneMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction);
        Long transactionOneMonths = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction_Return);
        Long transactionReturnOneMonths = certiTransactionInfoService.count(params);
        return R.ok().put("borrowInThreeMonths", borrowInThreeMonths)
                .put("borrowInReturnThreeMonths", borrowInReturnThreeMonths)
                .put("borrowOutThreeMonths", borrowOutThreeMonths)
                .put("borrowOutReturnThreeMonths", borrowOutReturnThreeMonths)
                .put("transactionThreeMonths", transactionThreeMonths)
                .put("transactionReturnThreeMonths", transactionReturnThreeMonths)
                .put("borrowInTwoMonths", borrowInTwoMonths)
                .put("borrowInReturnTwoMonths", borrowInReturnTwoMonths)
                .put("borrowOutTwoMonths", borrowOutTwoMonths)
                .put("borrowOutReturnTwoMonths", borrowOutReturnTwoMonths)
                .put("transactionTwoMonths", transactionTwoMonths)
                .put("transactionReturnTwoMonths", transactionReturnTwoMonths)
                .put("borrowInOneMonths", borrowInOneMonths)
                .put("borrowInReturnOneMonths", borrowInReturnOneMonths)
                .put("borrowOutOneMonths", borrowOutOneMonths)
                .put("borrowOutReturnOneMonths", borrowOutReturnOneMonths)
                .put("transactionOneMonths", transactionOneMonths)
                .put("transactionReturnOneMonths", transactionReturnOneMonths);
    }

    @RequestMapping("/bbCertTransacByJobCollect")
    @RequiresPermissions("certificate:certiTransactionInfo:list")
    public List<CollectInfo> bbCertTransacByJobCollect() {

        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        List<CollectInfo> borrowInCertList = certiTransactionInfoService.CertiTransactionByJobParams(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        List<CollectInfo> borrowOutCertList = certiTransactionInfoService.CertiTransactionByJobParams(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.Transaction);
        List<CollectInfo> TransactionCertList = certiTransactionInfoService.CertiTransactionByJobParams(params);
        List<CollectInfo> collectInfoList = new ArrayList<>();

        List<String> dateList = new ArrayList<>();
        if (CollectionUtils.isEmpty(borrowInCertList) && CollectionUtils.isEmpty(borrowOutCertList) && CollectionUtils.isEmpty(TransactionCertList)) {
            return collectInfoList;
        }

        borrowInCertList.forEach((b) -> {
            if (b.getD() != null) {
                dateList.add(b.getD());
            }
        });

        borrowOutCertList.forEach((b) -> {
            if (!dateList.contains(b.getD()) && b.getD() != null) {
                dateList.add(b.getD());
            }
        });

        TransactionCertList.forEach((b) -> {
            if (!dateList.contains(b.getD()) && b.getD() != null) {
                dateList.add(b.getD());
            }
        });

        dateList.forEach((d) -> {
            CollectInfo co = new CollectInfo();
            co.setD(d);

            int num = 0;
            for (CollectInfo c : borrowInCertList) {
                if (c.getD() != null && c.getD().equals(d)) {
                    num = c.getNum();
                }
            }
            co.setBorrowInNum(num);

            num = 0;
            for (CollectInfo c : borrowOutCertList) {
                if (c.getD() != null && c.getD().equals(d)) {
                    num = c.getNum();
                }
            }
            co.setBorrowOutNum(num);

            num = 0;
            for (CollectInfo c : TransactionCertList) {
                if (c.getD() != null && c.getD().equals(d)) {
                    num = c.getNum();
                }
            }
            co.setTransactionNum(num);
            collectInfoList.add(co);
        });

        return collectInfoList;
    }

    @RequestMapping("/count")
    @RequiresPermissions("certificate:certiTransactionInfo:list")
    public R count(@RequestParam Map<String, Object> params, HttpServletRequest request) {
        String tenantId = request.getParameter("tenantId");
        String certificateId = request.getParameter("certificateId");
        String type = request.getParameter("type");
        String certificateType = request.getParameter("certificateType");
        String keepDeptId = request.getParameter("keepDeptId");
        String keepUserId = request.getParameter("keepUserId");
        String name = request.getParameter("name");
        String idType = request.getParameter("idType");
        String idCard = request.getParameter("idCard");
        String certificateNo = request.getParameter("certificateNo");
        String mobile = request.getParameter("mobile");
        String profession = request.getParameter("profession");
        String academic = request.getParameter("academic");
        String releaseTime = request.getParameter("releaseTime");
        String validityEndTime = request.getParameter("validityEndTime");
        String validityType = request.getParameter("validityType");
        String months = request.getParameter("months");
        String orderBy = request.getParameter("orderBy");
        String inOrder = request.getParameter("inOrder");
        String days = request.getParameter("days");

        if (StringUtils.isNotBlank(certificateType)) {
            params.put("certificateType", Integer.parseInt(certificateType));
        }

        if (StringUtils.isNotBlank(keepDeptId)) {
            params.put("keepDeptId", Long.parseLong(keepDeptId));
        }

        if (StringUtils.isNotBlank(keepUserId)) {
            params.put("keepUserId", Long.parseLong(keepUserId));
        }

        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }

        if (StringUtils.isNotBlank(idType)) {
            params.put("idType", idType);
        }

        if (StringUtils.isNotBlank(idCard)) {
            params.put("idCard", idCard);
        }

        if (StringUtils.isNotBlank(certificateNo)) {
            params.put("certificateNo", certificateNo);
        }

        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }

        if (StringUtils.isNotBlank(profession)) {
            params.put("profession", profession);
        }

        if (StringUtils.isNotBlank(academic)) {
            params.put("academic", academic);
        }

        if (StringUtils.isNotBlank(releaseTime)) {
            params.put("releaseTime", DateUtils.strToDate(releaseTime));
        }

        if (StringUtils.isNotBlank(validityEndTime)) {
            params.put("validityEndTime", DateUtils.strToDate(validityEndTime));
        }

        if (StringUtils.isNotBlank(type)) {
            params.put("type", type);
        }

        if (StringUtils.isNotBlank(orderBy)) {
            if ("type".equals(orderBy)) {
                orderBy = "t.type";
            }
            params.put("orderBy", com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(orderBy));
        }

        if (StringUtils.isNotBlank(inOrder)) {
            params.put("inOrder", inOrder);
        }

        if (StringUtils.isNotBlank(validityType)) {
            switch (validityType) {
                case "0":
                    params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    break;
                case "-1":
                    params.put("ivalidity", "ivalidity");
                    break;
                case "2":
                    if (StringUtils.isNotBlank(months)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    }
                    if (StringUtils.isNotBlank(days)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(Integer.parseInt(days)));
                    }
                    break;
                default:
                    params.put("validity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    break;
            }
        }

        if (StringUtils.isNotBlank(tenantId)) {
            params.put("tenantId", tenantId);
        }

        if (StringUtils.isNotBlank(certificateId)) {
            params.put("certificateId", Long.parseLong(certificateId));
        }

        long count = certiTransactionInfoService.count(params);

        return R.ok().put("count", count);
    }

    /**
     * 批量导出
     */
    @RequestMapping("/export")
    @RequiresPermissions("certificate:employeeInfo:list")
    public void export(HttpServletRequest request, HttpServletResponse response) {

        Map<String, Object> params = new HashMap<>();
        String tenantId = request.getParameter("tenantId");
        String certificateId = request.getParameter("certificateId");
        String type = request.getParameter("type");
        String certificateType = request.getParameter("certificateType");
        String keepDeptId = request.getParameter("keepDeptId");
        String keepUserId = request.getParameter("keepUserId");
        String name = request.getParameter("name");
        String pIdType = request.getParameter("idType");
        String idType = request.getParameter("idType");
        String idCard = request.getParameter("idCard");
        String certificateNo = request.getParameter("certificateNo");
        String mobile = request.getParameter("mobile");
        String profession = request.getParameter("profession");
        String academic = request.getParameter("academic");
        String releaseTime = request.getParameter("releaseTime");
        String validityEndTime = request.getParameter("validityEndTime");
        String validityType = request.getParameter("validityType");
        String months = request.getParameter("months");
        String days = request.getParameter("days");
        String orderBy = request.getParameter("orderBy");
        String inOrder = request.getParameter("inOrder");

        if (StringUtils.isNotBlank(certificateType)) {
            params.put("certificateType", Integer.parseInt(certificateType));
        }

        if (StringUtils.isNotBlank(keepDeptId)) {
            params.put("keepDeptId", Long.parseLong(keepDeptId));
        }

        if (StringUtils.isNotBlank(keepUserId)) {
            params.put("keepUserId", Long.parseLong(keepUserId));
        }

        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }

        if (StringUtils.isNotBlank(pIdType)) {
            params.put("pIdType", pIdType);
        }

        if (StringUtils.isNotBlank(idType)) {
            params.put("idType", idType);
        }

        if (StringUtils.isNotBlank(idCard)) {
            params.put("idCard", idCard);
        }

        if (StringUtils.isNotBlank(certificateNo)) {
            params.put("certificateNo", certificateNo);
        }

        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }

        if (StringUtils.isNotBlank(profession)) {
            params.put("profession", profession);
        }

        if (StringUtils.isNotBlank(academic)) {
            params.put("academic", academic);
        }

        if (StringUtils.isNotBlank(releaseTime)) {
            params.put("releaseTime", DateUtils.strToDate(releaseTime));
        }

        if (StringUtils.isNotBlank(validityEndTime)) {
            params.put("validityEndTime", DateUtils.strToDate(validityEndTime));
        }

        if (StringUtils.isNotBlank(type)) {
            params.put("type", type);
        }

        if (StringUtils.isNotBlank(orderBy)) {
            if ("type".equals(orderBy)) {
                orderBy = "t.type";
            }
            params.put("orderBy", com.internetCafes.spms.common.utils.StringUtils.HumpToUnderline(orderBy));
        }

        if (StringUtils.isNotBlank(inOrder)) {
            params.put("inOrder", inOrder);
        }

        if (StringUtils.isNotBlank(validityType)) {
            switch (validityType) {
                case "0":
                    if (StringUtils.isNotBlank(months)) {
                        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    }
                    if (StringUtils.isNotBlank(days)) {
                        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(Integer.parseInt(days)));
                    }
                    break;
                case "-1":
                    params.put("ivalidity", "");
                    break;
                case "2":
                    if (StringUtils.isNotBlank(months)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(Integer.parseInt(months)));
                    }
                    if (StringUtils.isNotBlank(days)) {
                        params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(Integer.parseInt(days)));
                    }
                    break;
            }
        }

        if (StringUtils.isNotBlank(tenantId)) {
            params.put("tenantId", tenantId);
        }

        if (StringUtils.isNotBlank(certificateId)) {
            params.put("certificateId", Long.parseLong(certificateId));
        }
        if (!params.containsKey("warn")) {
            params.put("warn", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(15));
        }
        if (!params.containsKey("statuses")) {
            params.put("statuses", CommonConstants.CertificateStatus.EXCEPT_DELETE);
        }
        List<CertiTransactionInfoVo> certiTransactionInfoVos = certiTransactionInfoService.selectByJobParams(params);
        try {
            if (certiTransactionInfoVos != null && certiTransactionInfoVos.size() > 0) {
                List<CertificateTransactionExcelPro> orderInfoExcelList = new ArrayList<>();
                CertificateTransactionExcelPro o;
                for (CertiTransactionInfoVo vo : certiTransactionInfoVos) {
                    o = new CertificateTransactionExcelPro();
                    BeanUtils.copyProperties(vo, o);
                    orderInfoExcelList.add(o);
                }
                ExcelUtils.exportExcel(orderInfoExcelList, "证书流转统计", "证书流转统计", CertificateTransactionExcelPro.class, "证书流转统计.xls", response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/warningCount")
    @RequiresPermissions("certificate:employeeInfo:list")
    public R countWarning() {
        Map<String, Object> params = new HashMap<>();
        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfDay(15));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        long fifteenDaysBorrowIn = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        long fifteenDaysBorrowOut = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        long fifteenDaysBorrowInReturn = certiTransactionInfoService.count(params);
        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(7));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        long sevenDaysBorrowIn = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        long sevenDaysBorrowOut = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        long sevenDaysBorrowInReturn = certiTransactionInfoService.count(params);
        params.put("beIvalidity", com.internetCafes.spms.core.utils.DateUtils.getBeAfMonth(3));
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        long threeDaysBorrowIn = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        long threeDaysBorrowOut = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        long threeDaysBorrowInReturn = certiTransactionInfoService.count(params);
        params = new HashMap<>();
        params.put("ivalidity", -1);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn);
        long countBorrowIn = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowOut);
        long countBorrowOut = certiTransactionInfoService.count(params);
        params.put("type", CommonConstants.CertiTransactionInfoType.BorrowIn_Return);
        long countBorrowInReturn = certiTransactionInfoService.count(params);
        return R.ok().put("fifteenDaysBorrowIn", fifteenDaysBorrowIn).put("fifteenDaysBorrowOut", fifteenDaysBorrowOut).put("fifteenDaysBorrowInReturn", fifteenDaysBorrowInReturn)
                .put("sevenDaysBorrowIn", sevenDaysBorrowIn).put("sevenDaysBorrowOut", sevenDaysBorrowOut).put("sevenDaysBorrowInReturn", sevenDaysBorrowInReturn)
                .put("threeDaysBorrowIn", threeDaysBorrowIn).put("threeDaysBorrowOut", threeDaysBorrowOut).put("threeDaysBorrowInReturn", threeDaysBorrowInReturn)
                .put("countBorrowIn", countBorrowIn).put("countBorrowOut", countBorrowOut).put("countBorrowInReturn", countBorrowInReturn);
    }
}
